<template>
  <div class="disaster-report-container">
    <div class="main-content">
      <!-- 地图容器 -->
      <div id="viewDiv" class="map-view"></div>

      <!-- 右侧功能面板 -->
      <div class="control-panel">
        <el-card class="control-card">
          <template #header>
            <div class="card-header">
              <span>灾难上报</span>
              <div class="water-drop"></div>
            </div>
          </template>
          <div class="control-buttons">
            <el-button type="primary" @click="startAddDisaster" class="disaster-button">
              <el-icon><Plus /></el-icon> 上报灾难
            </el-button>
          </div>
          <div class="operation-tip" v-if="!isAddingDisaster">
            <el-alert
              title="提示：点击上报灾难按钮开始上报"
              type="info"
              :closable="false"
              show-icon
              class="tip-alert"
            />
          </div>
        </el-card>
      </div>
    </div>

    <!-- 添加灾难表单对话框 -->
    <el-dialog
      v-model="showDisasterDialog"
      title="上报灾难信息"
      width="50%"
      destroy-on-close
      custom-class="disaster-dialog"
    >
      <el-form
        :model="disasterForm"
        label-width="120px"
        ref="disasterFormRef"
        :rules="formRules"
        class="disaster-form"
      >
        <!-- 位置选择方式 -->
        <el-form-item label="选择位置方式">
          <el-radio-group v-model="reportMethod" @change="handleReportMethodChange">
            <el-radio label="map">地图选点</el-radio>
            <el-radio label="manual">手动输入坐标</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 手动输入坐标 -->
        <template v-if="reportMethod === 'manual'">
          <el-form-item label="经度">
            <el-input-number
              v-model="manualCoordinates.longitude"
              :precision="6"
              :step="0.000001"
              :min="73"
              :max="135"
              style="width: 100%"
            ></el-input-number>
          </el-form-item>
          <el-form-item label="纬度">
            <el-input-number
              v-model="manualCoordinates.latitude"
              :precision="6"
              :step="0.000001"
              :min="18"
              :max="53"
              style="width: 100%"
            ></el-input-number>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="confirmManualCoordinates">确认位置</el-button>
          </el-form-item>
        </template>

        <!-- 地图选点提示 -->
        <el-form-item v-if="reportMethod === 'map' && isSelectingLocation" label="地图选点">
          <el-alert title="请关闭此对话框（不点取消），在地图上点击选择灾难位置" type="info" :closable="false" show-icon />
        </el-form-item>

        <!-- 已选择的位置信息 -->
        <el-form-item label="位置信息" v-if="newLocation">
          <div class="location-info">
            <el-tag type="success">已选择位置</el-tag>
            <div class="coordinate-display">
              <p>经度: {{ getWGS84Coordinates()[0].toFixed(6) }}</p>
              <p>纬度: {{ getWGS84Coordinates()[1].toFixed(6) }}</p>
            </div>
          </div>
        </el-form-item>

        <!-- 其他表单项 -->
        <el-form-item label="名称" prop="Name">
          <el-input v-model="disasterForm.Name" placeholder="请输入灾难名称"></el-input>
        </el-form-item>
        <el-form-item label="灾难类型" prop="DisasterType">
          <el-select
            v-model="disasterForm.DisasterType"
            placeholder="请选择灾难类型"
            style="width: 100%"
          >
            <el-option label="地震" value="地震"></el-option>
            <el-option label="洪水" value="洪水"></el-option>
            <el-option label="火灾" value="火灾"></el-option>
            <el-option label="泥石流" value="泥石流"></el-option>
            <el-option label="台风" value="台风"></el-option>
            <el-option label="其他" value="其他"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="Description">
          <el-input
            v-model="disasterForm.Description"
            type="textarea"
            :rows="4"
            placeholder="请详细描述灾难情况"
          ></el-input>
        </el-form-item>
        <el-form-item label="现场照片">
          <div class="upload-container">
            <el-upload
              class="avatar-uploader"
              :auto-upload="false"
              :show-file-list="false"
              :on-change="handlePhotoChange"
              accept="image/*"
            >
              <img v-if="disasterForm.Photo" :src="disasterForm.Photo" class="avatar" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
            <div class="upload-tip" v-if="disasterForm.Photo">
              <el-button size="small" type="danger" @click="removePhoto">删除照片</el-button>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelDisasterOperation">取消</el-button>
          <el-button type="primary" @click="saveDisaster" :disabled="!newLocation">
            提交上报
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 上报成功提示对话框 -->
    <el-dialog
      v-model="showSuccessDialog"
      title="上报成功"
      width="30%"
      custom-class="success-dialog"
    >
      <div class="success-content">
        <el-icon class="success-icon"><CircleCheckFilled /></el-icon>
        <p>灾难信息已成功上报，感谢您的贡献！</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="closeSuccessDialog">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { ElMessage, type FormInstance, type UploadFile } from 'element-plus'
import { Plus, CircleCheckFilled, ArrowRight } from '@element-plus/icons-vue'
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'
import Graphic from '@arcgis/core/Graphic'
import Point from '@arcgis/core/geometry/Point'
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol'
import gaodeLayer from '@/utils/GaoDeBaseLayer'
import gcoord from 'gcoord'

// 状态变量
const showDisasterDialog = ref(false)
const showSuccessDialog = ref(false)
const isAddingDisaster = ref(false)
const isSelectingLocation = ref(false)
const reportMethod = ref('map') // 上报方式：地图选点或手动输入
const manualCoordinates = ref({
  longitude: 117.0203, // 默认经度（济南）
  latitude: 36.6683, // 默认纬度（济南）
})
let newLocation: Point | null = null
let tempGraphic: Graphic | null = null
const disasterFormRef = ref<FormInstance | null>(null)

// 表单数据
const disasterForm = ref({
  Name: '',
  DisasterType: '',
  Description: '',
  Photo: '',
  DisasterMessageJson: '{}',
})

// 表单验证规则
const formRules = {
  Name: [{ required: true, message: '请输入灾难名称', trigger: 'blur' }],
  DisasterType: [{ required: true, message: '请选择灾难类型', trigger: 'change' }],
  Description: [{ required: true, message: '请输入灾难描述', trigger: 'blur' }],
}

// 地图和图层引用
let view: MapView | null = null
let disasterLayer: FeatureLayer | null = null

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  if (view) {
    view = null
  }
})

// 初始化地图
const initMap = () => {
  try {
    // 创建地图实例
    const map = new Map({
      basemap: {
        baseLayers: [gaodeLayer],
      },
    })

    // 创建地图视图
    view = new MapView({
      container: 'viewDiv',
      map: map,
      center: [117.0203, 36.6683], // 山东省济南市的经纬度
      zoom: 10,
    })

    // 创建灾难点要素图层
    disasterLayer = new FeatureLayer({
      url: 'https://services7.arcgis.com/chXsWZj8U6NqFZb6/arcgis/rest/services/DisasterDetectionAndRescueSystem/FeatureServer/0',
      outFields: ['*'], // 获取所有字段
      renderer: {
        type: 'simple',
        symbol: new SimpleMarkerSymbol({
          color: [255, 0, 0],
          outline: {
            color: [255, 255, 255],
            width: 2,
          },
          size: 12,
        }),
      },
      popupTemplate: {
        title: '{Name}',
        content: (feature: any) => {
          const attributes = feature.graphic.attributes;
          let content = `
            <div class="popup-content">
              <div class="popup-section">
                <h3>基本信息</h3>
                <p><strong>名称：</strong>${attributes.Name || '无'}</p>
                <p><strong>灾难类型：</strong>${attributes.DisasterType || '无'}</p>
                <p><strong>描述：</strong>${attributes.Description || '无'}</p>
              </div>
          `;

          // 检查是否有DisasterMessageJson数据
          if (attributes.DisasterMessageJson) {
            try {
              const messageData = JSON.parse(attributes.DisasterMessageJson);

              // 添加确认状态信息
              content += `
                <div class="popup-section">
                  <h3>状态信息</h3>
                  <p><strong>状态：</strong>${messageData.confirmed ? '已确认' : '未确认'}</p>
              `;

              if (messageData.confirmed) {
                content += `<p><strong>确认时间：</strong>${new Date(messageData.confirmTime).toLocaleString()}</p>`;
                if (messageData.confirmNote) {
                  content += `<p><strong>确认备注：</strong>${messageData.confirmNote}</p>`;
                }
              }

              content += `<p><strong>同步状态：</strong>${messageData.synced ? '已同步' : '未同步'}</p>`;
              if (messageData.synced && messageData.syncTime) {
                content += `<p><strong>同步时间：</strong>${new Date(messageData.syncTime).toLocaleString()}</p>`;
              }
              content += `</div>`;

              // 添加受灾情况数据
              if (messageData.disasterImpact) {
                const impact = messageData.disasterImpact;
                content += `
                  <div class="popup-section">
                    <h3>受灾情况</h3>
                    <p><strong>受灾人数：</strong>${impact.affectedPeople || 0} 人</p>
                    <p><strong>受伤人数：</strong>${impact.injuredPeople || 0} 人</p>
                    <p><strong>死亡人数：</strong>${impact.deathCount || 0} 人</p>
                    <p><strong>无家可归人数：</strong>${impact.homelessPeople || 0} 人</p>
                    <p><strong>经济损失：</strong>${impact.economicLoss || 0} 万元</p>
                    <p><strong>受灾面积：</strong>${impact.affectedArea || 0} km²</p>
                    <p><strong>救援队伍数量：</strong>${impact.rescueTeams || 0} 个</p>
                    <p><strong>救援人员数量：</strong>${impact.rescuePersonnel || 0} 人</p>
                  </div>
                `;
              }
            } catch (e) {
              console.error('解析DisasterMessageJson失败:', e);
            }
          }

          content += `</div>`;
          return content;
        },
        outFields: ['*'],
      },
    })

    // 添加图层到地图
    map.add(disasterLayer)

    // 添加点击事件
    view.on('click', (event) => {
      if (isAddingDisaster.value && isSelectingLocation.value) {
        // 如果正在添加灾难并且在选择位置状态，记录点击位置
        newLocation = view!.toMap(event)

        // 添加临时标记
        addTempMarker(
          new Point({
            x: newLocation.x,
            y: newLocation.y,
            spatialReference: view!.spatialReference,
          }),
        )

        // 选择位置后，关闭选择位置状态
        isSelectingLocation.value = false
        // 显示填写信息对话框
        showDisasterDialog.value = true
        return
      }
    })
  } catch (error) {
    console.error('初始化地图失败:', error)
    ElMessage.error('初始化地图失败')
  }
}

// 添加临时标记
const addTempMarker = (location: Point) => {
  // 移除之前的临时标记
  if (tempGraphic && view) {
    view.graphics.remove(tempGraphic)
  }

  // 创建新的临时标记
  tempGraphic = new Graphic({
    geometry: location,
    symbol: new SimpleMarkerSymbol({
      color: [255, 0, 0],
      outline: {
        color: [255, 255, 255],
        width: 2,
      },
      size: 12,
    }),
  })

  // 添加到视图
  if (view) {
    view.graphics.add(tempGraphic)
  }
}

// 开始添加灾难
const startAddDisaster = () => {
  isAddingDisaster.value = true
  reportMethod.value = 'map' // 默认使用地图选点方式
  isSelectingLocation.value = true
  newLocation = null
  showDisasterDialog.value = true // 直接打开对话框

  // 重置表单
  disasterForm.value = {
    Name: '',
    DisasterType: '',
    Description: '',
    Photo: '',
    DisasterMessageJson: '{}',
  }

  // 重置手动坐标
  manualCoordinates.value = {
    longitude: 117.0203,
    latitude: 36.6683,
  }
}

// 处理上报方式变化
const handleReportMethodChange = (value: string) => {
  if (value === 'map') {
    isSelectingLocation.value = true
    ElMessage.info('请在地图上点击选择灾难位置')
  } else {
    isSelectingLocation.value = false
    ElMessage.info('请输入灾难位置的经纬度坐标')
  }
}

// 添加坐标输入验证
const validateCoordinates = () => {
  if (!manualCoordinates.value.longitude || !manualCoordinates.value.latitude) {
    ElMessage.warning('请输入完整的经纬度坐标')
    return false
  }

  // 验证经度范围
  if (manualCoordinates.value.longitude < 73 || manualCoordinates.value.longitude > 135) {
    ElMessage.warning('经度必须在73-135度之间')
    return false
  }

  // 验证纬度范围
  if (manualCoordinates.value.latitude < 18 || manualCoordinates.value.latitude > 53) {
    ElMessage.warning('纬度必须在18-53度之间')
    return false
  }

  return true
}

// 确认手动输入的坐标
const confirmManualCoordinates = () => {
  // 先进行验证
  if (!validateCoordinates()) {
    return
  }

  // 创建点位置
  const spatialReference = view?.spatialReference || { wkid: 3857 }

  // 将WGS84坐标转换为Web Mercator坐标
  const mercatorCoords = gcoord.transform(
    [manualCoordinates.value.longitude, manualCoordinates.value.latitude],
    gcoord.WGS84,
    gcoord.EPSG3857,
  )

  newLocation = new Point({
    x: mercatorCoords[0],
    y: mercatorCoords[1],
    spatialReference: spatialReference,
  })

  // 添加临时标记
  addTempMarker(newLocation)

  // 将地图中心移动到该位置并放大
  if (view) {
    view.goTo(
      {
        center: [mercatorCoords[0], mercatorCoords[1]],
        zoom: 15,
      },
      { duration: 1000 },
    )
  }

  // 显示填写信息对话框
  showDisasterDialog.value = true
}

// 取消操作
const cancelDisasterOperation = () => {
  showDisasterDialog.value = false
  isAddingDisaster.value = false
  isSelectingLocation.value = false // 重置选择位置状态

  // 清除临时标记
  if (tempGraphic && view) {
    view.graphics.remove(tempGraphic)
  }
  newLocation = null
}

// 保存灾难信息
const saveDisaster = async () => {
  if (!disasterFormRef.value) return

  try {
    // 表单验证
    await disasterFormRef.value.validate()

    // 准备属性数据 - 确保所有字段类型正确
    const attributes: any = {
      Name: String(disasterForm.value.Name),
      DisasterType: String(disasterForm.value.DisasterType),
      Description: String(disasterForm.value.Description),
      Photo: String(disasterForm.value.Photo || ''),
      DisasterMessageJson: '{}',
    }

    // 添加新灾难点
    if (!newLocation || !disasterLayer) {
      ElMessage.error('请先在地图上选择位置')
      return
    }

    // 创建新要素
    const newFeature = new Graphic({
      geometry: newLocation,
      attributes: attributes,
    })

    try {
      // 添加到图层
      const results = await disasterLayer.applyEdits({
        addFeatures: [newFeature],
      })

      if (results.addFeatureResults && results.addFeatureResults.length > 0) {
        // 显示成功对话框
        showSuccessDialog.value = true

        // 清除临时标记
        if (tempGraphic && view) {
          view.graphics.remove(tempGraphic)
        }
      } else {
        ElMessage.error('上报灾难失败')
      }
    } catch (error) {
      console.error('上报灾难时出错:', error)
      ElMessage.error('上报灾难失败，请稍后重试')
    }

    // 关闭对话框
    showDisasterDialog.value = false
  } catch (error) {
    console.error('保存灾难信息失败:', error)
    ElMessage.error('表单验证失败，请检查输入')
  }
}

// 处理照片上传并转换为base64
const handlePhotoChange = (file: UploadFile) => {
  const isImage = file.raw?.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return
  }

  // 图片大小限制（2MB）
  const isLt2M = file.size! / 1024 / 1024 < 2
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过2MB!')
    return
  }

  // 压缩并转换图片为base64
  compressImage(file.raw as File, 800, 0.7)
}

// 压缩图片
const compressImage = (file: File, maxWidth: number, quality: number) => {
  const reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = (e) => {
    const img = new Image()
    img.src = e.target?.result as string
    img.onload = () => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')

      // 计算压缩后的尺寸，保持宽高比
      let width = img.width
      let height = img.height
      if (width > maxWidth) {
        height = (height * maxWidth) / width
        width = maxWidth
      }

      canvas.width = width
      canvas.height = height
      ctx?.drawImage(img, 0, 0, width, height)

      // 转换为base64并设置到表单
      const base64 = canvas.toDataURL('image/jpeg', quality)
      disasterForm.value.Photo = base64
    }
  }
}

// 删除照片
const removePhoto = () => {
  disasterForm.value.Photo = ''
}

// 关闭成功对话框并重置状态
const closeSuccessDialog = () => {
  showSuccessDialog.value = false
  isAddingDisaster.value = false
  newLocation = null
  if (tempGraphic && view) {
    view.graphics.remove(tempGraphic)
    tempGraphic = null
  }
}

// 获取WGS84坐标系的经纬度
const getWGS84Coordinates = () => {
  if (!newLocation) return [0, 0]

  // 将Web Mercator坐标转换为WGS84坐标
  return gcoord.transform([newLocation.x, newLocation.y], gcoord.EPSG3857, gcoord.WGS84)
}
</script>

<style scoped>
.disaster-report-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.main-content {
  display: flex;
  height: 100%;
  padding: 16px;
  box-sizing: border-box;
  gap: 16px;
}

.map-view {
  flex: 1;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  min-height: 500px;
}

.control-panel {
  width: 350px;
  z-index: 10;
  display: flex;
  flex-direction: column;
}

.control-card {
  background-color: rgba(255, 255, 255, 0.98);
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  border: none;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  color: #2c3e50;
  font-weight: bold;
  font-size: 18px;
  padding-bottom: 8px;
  border-bottom: 2px solid #eaeaea;
}

.water-drop {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 30px;
  height: 30px;
  background-color: rgba(64, 158, 255, 0.2);
  border-radius: 50%;
  z-index: -1;
}

.control-buttons {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
  margin-top: 10px;
}

.disaster-button {
  width: 100%;
  margin-top: 16px;
  height: 44px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 8px;
}

.location-selection-tip {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  width: 300px;
}

.upload-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.avatar-uploader {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 178px;
  height: 178px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.avatar-uploader:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
  object-fit: cover;
}

.upload-tip {
  margin-top: 10px;
}

.mt-2 {
  margin-top: 16px;
  text-align: center;
}

.continue-button {
  width: 80%;
  border-radius: 8px;
  font-weight: 500;
}

.location-title {
  font-size: 16px;
  font-weight: 500;
  color: #2c3e50;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #eaeaea;
}

.coordinate-value {
  font-family: 'Courier New', monospace;
  color: #409eff;
  font-weight: 500;
}

.tip-alert {
  margin-top: 16px;
  border-radius: 8px;
}

.success-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 30px 0;
  background-color: #f0f9eb;
  border-radius: 8px;
}

.success-icon {
  font-size: 48px;
  color: #67c23a;
  margin-bottom: 16px;
}

.disaster-dialog .el-dialog__header {
  padding: 20px;
  border-bottom: 1px solid #eaeaea;
}

.disaster-dialog .el-dialog__body {
  padding: 24px 20px;
}

.disaster-form .el-form-item__label {
  font-weight: 500;
}

.success-dialog .el-dialog__header {
  background-color: #f0f9eb;
  padding: 16px 20px;
  border-bottom: 1px solid #e1f3d8;
}

.success-dialog .el-dialog__body {
  padding: 24px;
}

.disaster-descriptions {
  margin-top: 8px;
}

.report-method {
  margin: 16px 0;
}

.manual-coordinates {
  margin: 16px 0;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 8px;
}

.coordinate-form .el-form-item {
  margin-bottom: 16px;
}

.coordinate-display {
  margin-top: 10px;
  padding: 8px;
  background-color: #f0f9eb;
  border-radius: 4px;
  font-size: 14px;
}

.coordinate-display p {
  margin: 4px 0;
  font-family: monospace;
}

.location-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
</style>
